2023-04-30
#Typescript

【TS技巧】通过 in 操作符将联合类型转换为另一个联合类型

【TS技巧】通过 in 操作符将联合类型转换为另一个联合类型
首先,我们给出下面👇🏻这段代码,我们期望将当前实体单独转换为 user post comment
export type Entity = | { type: "user" } | { type: "post" } | { type: "comment" } const user:EntityWithId = { type: "user" userId: string } const post:EntityWithId = { type: "post" postId: string } const comment:EntityWithId = { type: "comment" commentId: string }
我们手动的给每个类型增加对应的 id 属性就是实现了我们所期望的 EntityWithId
type EntityWithId = | { type: "user" userId: string } | { type: "post" postId: string } | { type: "comment" commentId: string }
但是这看起来有些繁琐,我们该如何优化它呢?首先,我们先使用[Key in Type] 语法来遍历我们每个实体的type,并添加一个type属性, 属性值为我们每次遍历实体的 type值类型
type EntityWithId = { [EntityType in Entity['type']]:{ type:EntityType } }
然后,我们将这个对象类型转换为联合类型
type EntityWithId = { [EntityType in Entity['type']]:{ type:EntityType } }[Entity["type"]]
这意味着我们可以单独得到 user 类型 comment类型 或者post类型
const result = (EntityWithId = { type: "comment", })
当然这还没结束,我们还需要添加相应的id属性,这时候就需要使用 Record 方法,将id属性变为动态的
type EntityWithId = { [EntityType in Entity["type"]]: { type: EntityType } & Record<`${EntityType}Id`, string>//与EntityType拼接实现动态ID }[Entity["type"]]
这样就可以实现我们想要的结果🎉
const commentResult: EntityWithId = { type: "comment", commentId: "123", } const userResult: EntityWithId = { type: "user", userId: "123", } const postResult: EntityWithId = { type: "post", postId: "123", }
End of Article